package cn.flant.cmd;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import cn.flant.io.tcp.TcpServer;

public class CommandServer extends TcpServer {
	private Map<String, CommandHandler> commandCache = new ConcurrentHashMap<String, CommandHandler>();
	private Class<? extends RequestParser> requestParserClass = DefaultRequestParser.class;
	private Class<? extends ResponseBuilder> responseBuilderClass = DefaultResponseBuilder.class;
	private FilterChain filterChain = new FilterChain();

	public CommandServer(int port) {
		super(port, CommandSocketHandler.class);
	}

	public Class<? extends RequestParser> getRequestParserClass() {
		return requestParserClass == null ? DefaultRequestParser.class : requestParserClass;
	}

	public void setRequestParserClass(Class<? extends RequestParser> requestParserClass) {
		this.requestParserClass = requestParserClass;
	}

	public Class<? extends ResponseBuilder> getResponseBuilderClass() {
		return responseBuilderClass == null ? DefaultResponseBuilder.class : responseBuilderClass;
	}

	public void setResponseBuilderClass(Class<? extends ResponseBuilder> responseBuilderClass) {
		this.responseBuilderClass = responseBuilderClass;
	}

	public void registCommandHandler(String name, CommandHandler handler) {
		if (handler == null) {
			throw new IllegalArgumentException("command handler can not be null");
		}
		if (name == null || name.trim().length() == 0) {
			throw new IllegalArgumentException("command name can not be null");
		}
		name = name.trim().toLowerCase();
		if (commandCache.containsKey(name)) {
			throw new IllegalArgumentException("command name is registered: " + name);
		}
		commandCache.put(name, handler);
	}

	public void unregistCommandHandler(String name) {
		commandCache.remove(name.toLowerCase());
	}

	protected CommandHandler getCommandHandler(String name) {
		return commandCache.get(name.toLowerCase());
	}

	public FilterChain getFilterChain() {
		return filterChain;
	}
}
